from datetime import datetime
from fastapi import status
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse, Response, StreamingResponse
from pydantic import BaseModel
from typing import Any, Dict, Optional
from common.config.constant import HttpStatusConstant


class ResponseUtil:
    """
    响应工具类
    """

    @classmethod
    def success(
            cls,

            data: Optional[Any] = None,
    ) -> Response:



        return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder(data))

    @classmethod
    def failure(
            cls,
            msg: str = '操作失败',
    ) -> Response:
        """
        失败响应方法

        :param msg: 可选，自定义失败响应信息
        :param data: 可选，失败响应结果中属性为data的值
        :param rows: 可选，失败响应结果中属性为rows的值
        :param dict_content: 可选，dict类型，失败响应结果中自定义属性的值
        :param model_content: 可选，BaseModel类型，失败响应结果中自定义属性的值
        :return: 失败响应结果
        """




        return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=jsonable_encoder(msg))

    @classmethod
    def unauthorized(
            cls,
            msg: str = '登录信息已过期，访问系统资源失败',
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> Response:
        """
        未认证响应方法

        :param msg: 可选，自定义未认证响应信息
        :param data: 可选，未认证响应结果中属性为data的值
        :param rows: 可选，未认证响应结果中属性为rows的值
        :param dict_content: 可选，dict类型，未认证响应结果中自定义属性的值
        :param model_content: 可选，BaseModel类型，未认证响应结果中自定义属性的值
        :return: 未认证响应结果
        """
        result = {'code': HttpStatusConstant.UNAUTHORIZED, 'msg': msg}

        if data is not None:
            result['data'] = data
        if rows is not None:
            result['rows'] = rows
        if dict_content is not None:
            result.update(dict_content)
        if model_content is not None:
            result.update(model_content.model_dump())

        result.update({'success': False, 'time': datetime.now()})

        return JSONResponse(status_code=status.HTTP_401_UNAUTHORIZED, content=jsonable_encoder(msg))

    @classmethod
    def forbidden(
            cls,
            msg: str = '该用户无此接口权限',
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> Response:
        """
        未授权响应方法

        :param msg: 可选，自定义未授权响应信息
        :param data: 可选，未授权响应结果中属性为data的值
        :param rows: 可选，未授权响应结果中属性为rows的值
        :param dict_content: 可选，dict类型，未授权响应结果中自定义属性的值
        :param model_content: 可选，BaseModel类型，未授权响应结果中自定义属性的值
        :return: 未授权响应结果
        """
        result = {'code': HttpStatusConstant.FORBIDDEN, 'msg': msg}

        if data is not None:
            result['data'] = data
        if rows is not None:
            result['rows'] = rows
        if dict_content is not None:
            result.update(dict_content)
        if model_content is not None:
            result.update(model_content.model_dump())

        result.update({'success': False, 'time': datetime.now()})

        return JSONResponse(status_code=status.HTTP_403_FORBIDDEN, content=jsonable_encoder(msg))

    @classmethod
    def error(
            cls,
            msg: str = '接口异常',
            data: Optional[Any] = None,
            rows: Optional[Any] = None,
            dict_content: Optional[Dict] = None,
            model_content: Optional[BaseModel] = None,
    ) -> Response:
        """
        错误响应方法

        :param msg: 可选，自定义错误响应信息
        :param data: 可选，错误响应结果中属性为data的值
        :param rows: 可选，错误响应结果中属性为rows的值
        :param dict_content: 可选，dict类型，错误响应结果中自定义属性的值
        :param model_content: 可选，BaseModel类型，错误响应结果中自定义属性的值
        :return: 错误响应结果
        """
        result = {'code': HttpStatusConstant.ERROR, 'msg': msg}

        if data is not None:
            result['data'] = data
        if rows is not None:
            result['rows'] = rows
        if dict_content is not None:
            result.update(dict_content)
        if model_content is not None:
            result.update(model_content.model_dump())

        result.update({'success': False, 'time': datetime.now()})

        return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=jsonable_encoder(msg))

    @classmethod
    def streaming(cls, *, data: Any = None):
        """
        流式响应方法

        :param data: 流式传输的内容
        :return: 流式响应结果
        """
        return StreamingResponse(status_code=status.HTTP_200_OK, content=data)
    @classmethod
    def excel_streaming(cls, *, data: Any = None,file_name: str= '文件'):
        """
        流式响应方法

        :param data: 流式传输的内容
        :return: 流式响应结果
        """
        response = StreamingResponse(data, media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        from urllib.parse import quote
        # 设置响应头，指定文件名
        # 使用quote对文件名进行URL编码
        quoted_file_name = quote(file_name)
        response_headers = f"attachment; filename*=UTF-8''{quoted_file_name}.xlsx"
        response.headers["Content-Disposition"] = response_headers
        return response

    @classmethod
    def png_streaming(cls, *, data: Any = None, file_name: str = '图片'):
        response = StreamingResponse(data, media_type='image/png')
        from urllib.parse import quote
        # 设置响应头，指定文件名
        # 使用quote对文件名进行URL编码
        quoted_file_name = quote(file_name)
        response_headers = f"attachment; filename*=UTF-8''{quoted_file_name}.png"
        response.headers["Content-Disposition"] = response_headers
        return response
    @classmethod
    def all_streaming(cls, *, data: Any = None, file_name: str = 'demo'):
        # 获取文件扩展名
        file_ext = file_name.split('.')[-1] if '.' in file_name else None
        media_type= None
        import mimetypes
        from urllib.parse import quote
        # 如果没有明确指定媒体类型，尝试猜测
        if file_ext:
            media_type = mimetypes.guess_type(f"file.{file_ext}")[0]
        else:
            media_type = "application/octet-stream"  # 默认二进制流
        # 创建流式响应
        response = StreamingResponse(data, media_type=media_type)
        # 设置响应头，指定文件名
        quoted_file_name = quote(file_name)
        response.headers["Content-Disposition"] = f"attachment; filename*=UTF-8''{quoted_file_name}"
        return response

